<?php

namespace App\Trip\Plane\Interfaces\Result\Abstracts;

use App\Models\Plane\Airports\Repositories\Interfaces\AirportRepositoryInterface;
use App\Trip\Enums\Plane\PlaneProviders;
use App\Trip\Plane\PlaneInfo\FlightInfo;
use App\Trip\Plane\Requests\CommonQueryInterface;
use Carbon\Carbon;

abstract class AbstractFlightQueryOneResult
{
    protected ?CommonQueryInterface $request = null; // 不打折
    protected PlaneProviders        $provider;
    /**
     * @var AirportRepositoryInterface
     */
    protected AirportRepositoryInterface $flightRepo;
    protected FlightInfo                 $flight_info;
    protected string                     $main_flight_no          = '';
    protected string                     $main_company_name       = '';
    protected string                     $main_company_short_name = '';

    public function __construct()
    {
        $this->flightRepo = app(AirportRepositoryInterface::class);
        // 航班基础信息
        $this->setBaseFlight();
    }

    private function setBaseFlight(): void
    {
        $flight_info = new FlightInfo();
        $this->setFlightInfo($flight_info);
    }

    public abstract function getArriveAt();

    public function getFlightInfo(): FlightInfo
    {
        return $this->flight_info;
    }

    public function setFlightInfo(FlightInfo $flightInfo): void
    {
        $this->flight_info = $flightInfo;
    }

    /**
     * 单个航班的信息
     * @return array
     */
    public function getInfo(): array
    {
        $info = [
            "provider"              => $this->getProvider()->value,
            "discount"              => $this->getDiscount(), // 通过 舱位 获取最小值
            "flight_no"             => $this->getFlightNo(),
            "main"                  => $this->getMain(), // 共享航班
            "comfort_flight_no"     => $this->main_flight_no ?: $this->getFlightNo(), // 用于舒适度查询
            "flight_price"          => $this->getCheckPrice(), // 需要加计算价格  ... 显示最低价
            "stock"                 => $this->getStock(),
            "stocks"                => $this->getStocks(),
            "depart_time"           => $this->getDepartTime(),
            "arrive_time"           => $this->getArriveTime(),
            "distance"              => $this->getDistance(),
            "run_time"              => $this->getRunTimes(),
            "from_code"             => $this->getDepartCode(),
            "to_code"               => $this->getArriveCode(),
            "punctuality_rate"      => $this->getPunctualityRate(), // 准时率
            "from_tower"            => $this->getFromTower(),
            "to_tower"              => $this->getToTower(),
            "from_name"             => $this->getDepartName(),
            "from_name_uy"          => $this->getDepartNameUy(),
            "to_name"               => $this->getArriveName(),
            "to_name_uy"            => $this->getArriveNameUy(),
            "short_from_name"       => $this->getDepartName(true),
            "short_from_name_uy"    => $this->getDepartNameUy(true),
            "short_to_name"         => $this->getArriveName(true),
            "short_to_name_uy"      => $this->getArriveNameUy(true),
            "construction_fee"      => $this->getConstructionFee(),
            "fuel_fee"              => $this->getFuelFee(),
            "day_difference"        => $this->getDayDifference(),
            "arrive_date"           => $this->getArriveDate(),
            "depart_date"           => $this->getDepartDate(),
            "company_name"          => $this->getCarrierName(),
            "company_name_uy"       => $this->getCarrierNameUy(),
            "company_short_name"    => $this->getCarrierName(true),
            "company_short_name_uy" => $this->getCarrierNameUy(true),
            "carrier_code"          => $this->getCarrierCode(),
            "plane_type"            => $this->getPlaneType(),
            "plane_size"            => $this->getPlaneSize(),
            "plane_size_uy"         => $this->getPlaneSizeUy(),
            "plane_type_name"       => $this->getPlaneTypeName(),
            "plane_type_name_uy"    => $this->getPlaneTypeNameUy(),
            "stop"                  => $this->getStops(),
            "meal"                  => $this->getMeal(),
            "meal_type"             => $this->getMealType(),
            "meal_type_uy"          => "",
            "tag"                   => "",
            "cabin"                 => $this->getCabin(),
            "cabin_type"            => '',
            "cabin_name"            => $this->getCabinName(),
            "cabin_name_uy"         => $this->getCabinNameUy(),
            "check_prices"          => $this->getCheckPrices(),
            'construction_fees'     => $this->getProviderConstructionFees(),
            'fuel_fees'             => $this->getProviderFuelFees(),
        ];

        $info['variflight'] = $this->variflight();


        if (!empty($this->getVendors())) {
            $info['vendors'] = $this->getVendors();
        }
        return $info;
    }

    public function getProvider(): PlaneProviders
    {
        return $this->provider;
    }

    public abstract function getDiscount();

    public abstract function getFlightNo();

    private function getMain(): array
    {
        //主飞航司
        //主飞航司二字码，非共享航班为空字符串
        if (!$this->main_flight_no) {
            return [];
        }
        return [
            'flight_no'          => $this->main_flight_no,
            'company_name'       => $this->main_company_name,
            'company_short_name' => $this->main_company_short_name,
        ];
    }

    public abstract function getCheckPrice();

    public abstract function getStock();

    public abstract function getStocks();

    public abstract function getDepartTime();

    public abstract function getArriveTime();

    public abstract function getDistance();

    public abstract function getRunTimes();

    public abstract function getDepartCode();

    public abstract function getArriveCode();

    /**
     * 准点率
     */
    public abstract function getPunctualityRate();

    public abstract function getFromTower();

    public abstract function getToTower();

    public abstract function getDepartName($short = false);

    public abstract function getDepartNameUy($short = false);

    public abstract function getArriveName($short = false);

    public abstract function getArriveNameUy($short = false);

    public abstract function getConstructionFee();

    public abstract function getFuelFee();

    public abstract function getDayDifference();

    public abstract function getArriveDate();

    public abstract function getDepartDate();

    public abstract function getCarrierName($short = false);

    public abstract function getCarrierNameUy($short = false);

    public abstract function getCarrierCode();

    public abstract function getPlaneType();

    public abstract function getPlaneSize();

    public abstract function getPlaneSizeUy();

    public abstract function getPlaneTypeName();

    public abstract function getPlaneTypeNameUy();

    public abstract function getStops(): array;

    public abstract function getMeal(): int;

    public abstract function getMealType();

    public abstract function getCabin();

    public abstract function getCabinName();

    public abstract function getCabinNameUy();

    public abstract function getCheckPrices();

    public abstract function getProviderConstructionFees(): array;

    public abstract function getProviderFuelFees(): array;

    private function variflight()
    {
        if ($this->request) {
//            $v   = new Variflight();
//            $res = $v->queryByDateAndCity($this->request);
//            return $res->findOneByFlightNo($this->getFlightNo());
        }

        return [];
    }

    public abstract function getVendors(): array;

    public function isDeparted(): bool
    {
        return Carbon::parse($this->getDepartAt())->lessThan(Carbon::now());
    }

    public abstract function getDepartAt();

}